Julia - Obrada slike - Detekcija ivica

In [5]:
#U okviru ove lekcije radićemo metode detekcije ivica
In [6]:
#Kao i u slučaju sa izoštravanjem ivica, šum može imati uticaj na vrednosti prvog i drugog izvoda na pozicijama 
#koji odgovaraju piskelima naših slika.

#Zato je pre svega potrebno redukovati uticaj šuma na našu sliku, pa tek onda pristupiti detekciji ivica
In [7]:
#Iz tih razloga, najčešće se detekcija ivica na nekoj slici vrši u sledećim etapama:

#1) usrednjavanje slike - za cilj ima uklanjanje šuma
#2) detekcija potencijalnih ivica na našoj slici
#3) odlučivanje koji pikseli pripadaju ivicama, a koji ne
In [1]:
using TestImages, Images, ImageFiltering
In [2]:
img = load("slikaizo.jpg")
Out[2]:
In [3]:
usr_filt = [1 1 1; 1 8 1; 1 1 1];
usr_filt = usr_filt / sum(usr_filt);
println(typeof(img))
Array{Gray{Normed{UInt8,8}},2}
In [4]:
usr_slika = imfilter(img, centered(usr_filt), "symmetric")
Out[4]:
In [5]:
#Sledeći korak predstavlja 
#Sada vršimo određivanje parcijalnih izvoda naše slike, kako bismo imati određen gradijent
dx = [0 0 0; 0 -1 0; 0 1 0];
dy = [0 0 0; 0 -1 1; 0 0 0];   #ovi operatori sami po sebi nemaju osobinu da fitriraju šum i 
                               #da bi se oni koristili, potrebno je prvo usrednjiti sliku, što smo mi i uradili
                               #kasnije će biti demonstrirani i moderniji operatori, koji imaju ovu osobinu, ali i 
                               # još nekakve druge osobine
In [6]:
#Sada tražimo gradijent naše slike tj. njegov intenzitet:

dfx = imfilter(img,centered(dx),"symmetric");
dfy = imfilter(img,centered(dy),"symmetric");

#gradF_kv = dfx.^2 + dfy.^2; #zbog složenosti izračunavanja (treba još da se primeni i sqrt()) 
                             #često se izbegava direktno računanje intenziteta gradF
                               #Nego se koristi nekakva aproksimacija: Na primer:
(m,n) = size(dfx);
gradF_app = zeros(m,n);
for i in 1 : m, j in 1 : n
    gradF_app[i,j] = abs(dfx[i,j]) + abs(dfy[i,j]);
end
In [7]:
#Konačno, sada kada imamo informacije o potencijalnim ivicama, vršimo odlučivanje da li neki piksel pripada ivici
#ili ne pripada

maxF = gradF_app[1,1];
for i in 1 : m, j in 1 : n
    if gradF_app[i,j] > maxF
        maxF = gradF_app[i,j];
    end
end

mosaicview(img,gradF_app; nrow = 1 )
┌ Warning: `mosaicview(A1::AbstractArray, A2::AbstractArray; kwargs...)` is deprecated, use `mosaic(A1, A2; kwargs...)` instead.
│   caller = ip:0x0
└ @ Core :-1
Out[7]:
In [8]:
pripada_ivica = zeros(m,n);
T = 0.3 * maxF; #ideja je postaviti nekakav prag odlučivanja na osnovu koga naš algoritam donosi zaključak da 
                #li dati piksel pripada ivici ili ne - treba odabrati prag T tako da detekcija bude dovoljno dobra
for i in 1 : m, j in 1 : n
    if gradF_app[i,j] > T
        pripada_ivica[i,j] = 1;
    end
end

mosaicview(img,pripada_ivica; nrow = 1 )
Out[8]:
In [9]:
#Varirajući parametar T tako da on uzima vrednosti od 0 do gradijekta dobijaćemo različite rezultate detekcije
#Međutim za sve njih zajednički je sledeći problem - detalji koji se pojavljuju 
#na slikama takođe predsatavljaju nagle  promene na slikama i kao takvi će 
#u manjoj ili većoj meri (zavisno od parametra T) ulatiti u konačan rezultat obrade
#jer je vrednost intenziteta gradijenta u njima veoma velika
In [10]:
#Iz tog razloga treba pažljivo birati i kakav filtar koristimo za naše filtriranje, kao i na to da on bude dovoljno
#pogodan za kasnije procene šta može da bude ivica i da li neki piksel pripada ivici:

#Stoga su nastali i drugi operatori koji u sebi imaju ugrađene mogućnosti 
# i filtriranja i nalaženja parcijalnih izvoda
#koji služe za detekcije različitih tipova ivica (Sobel-ov operator, Robinsonov operator itd.)
In [11]:
#Sobelov operator za detekciju horizontalnih i vertikalnih ivica

dx = [-1 -2 -1; 0 0 0; +1 +2 +1] / 8;
dy = [-1 0 +1; -2 0 +2; -1 0 +1] / 8;  #sadrže i opciju filtriranja i računanja parcijalnih izvoda
                                       #Olična stvar kod ovog algoritma je ta što će on odlično vršiti
                                       #detekciju za niske pragove T

                                       #povećanjem praga T dolazi do slabije detekcije ivica, pa ovde treba
                                       #dobro odabrati parametar T tako da detekcija bude dobro odrađena
img = testimage("woman_blonde.tif");

dfx = imfilter(img,centered(dx),"symmetric");
dfy = imfilter(img,centered(dy),"symmetric");

(m,n) = size(dfx);
gradF_app = zeros(m,n);
for i in 1 : m, j in 1 : n
    gradF_app[i,j] = abs(dfx[i,j]) + abs(dfy[i,j]);
end

maxF = gradF_app[1,1];
for i in 1 : m, j in 1 : n
    if gradF_app[i,j] > maxF
        maxF = gradF_app[i,j];
    end
end


pripada_ivica1 = zeros(m,n);
T1 = 0.05 * maxF; 
for i in 1 : m, j in 1 : n
    if gradF_app[i,j] > T1
        pripada_ivica1[i,j] = 1;
    end
end

pripada_ivica2 = zeros(m,n);
T2 = 0.2 * maxF; 
for i in 1 : m, j in 1 : n
    if gradF_app[i,j] > T2
        pripada_ivica2[i,j] = 1;
    end
end

pripada_ivica3 = zeros(m,n);
T3 = 0.5 * maxF; 
for i in 1 : m, j in 1 : n
    if gradF_app[i,j] > T3
        pripada_ivica3[i,j] = 1;
    end
end

mosaicview(img,pripada_ivica1, pripada_ivica2, pripada_ivica3; nrow = 1 )
Out[11]:
In [12]:
#Sobelov operator za detekciju dijagonalnih ivica

dx = [-2 -1 0; -1 0 1; 0 +1 +2] / 8;
dy = [0 +1 +2; -1 0 +1; -2 -1 0] / 8;  #sadrže i opciju filtriranja i računanja parcijalnih izvoda
                                       #Olična stvar kod ovog algoritma je ta što će on odlično vršiti
                                       #detekciju za niske pragove T

                                       #povećanjem praga T dolazi do slabije detekcije ivica, pa ovde treba
                                       #dobro odabrati parametar T tako da detekcija bude dobro odrađena
img = testimage("woman_blonde.tif");

dfx = imfilter(img,centered(dx),"symmetric");
dfy = imfilter(img,centered(dy),"symmetric");

(m,n) = size(dfx);
gradF_app = zeros(m,n);
for i in 1 : m, j in 1 : n
    gradF_app[i,j] = abs(dfx[i,j]) + abs(dfy[i,j]);
end

maxF = gradF_app[1,1];
for i in 1 : m, j in 1 : n
    if gradF_app[i,j] > maxF
        maxF = gradF_app[i,j];
    end
end


pripada_ivica1 = zeros(m,n);
T1 = 0.05 * maxF; 
for i in 1 : m, j in 1 : n
    if gradF_app[i,j] > T1
        pripada_ivica1[i,j] = 1;
    end
end

pripada_ivica2 = zeros(m,n);
T2 = 0.2 * maxF; 
for i in 1 : m, j in 1 : n
    if gradF_app[i,j] > T2
        pripada_ivica2[i,j] = 1;
    end
end

pripada_ivica3 = zeros(m,n);
T3 = 0.5 * maxF; 
for i in 1 : m, j in 1 : n
    if gradF_app[i,j] > T3
        pripada_ivica3[i,j] = 1;
    end
end

mosaicview(img,pripada_ivica1, pripada_ivica2, pripada_ivica3; nrow = 1 )
Out[12]:
In [14]:
#Za kraj, navešćemo i demonstraciju korišćenja Laplasovog operatora za detekciju ivica

img = testimage("lena_gray_512.tif");

usr_filt = [1 1 1; 1 8 1; 1 1 1];
usr_filt = usr_filt / sum(usr_filt);

usr_slika = imfilter(img, centered(usr_filt), "symmetric"); #Laplasov operator je osetljiv na šum, pa je kod njega poželjno
                               
#vršenje filtriranja
lap1 = [0 1 0; 1 -4 1; 0 1 0];
sl1_lap = imfilter(img, centered(lap1), "symmetric");

mosaicview(img, sl1_lap; nrow = 1)
Out[14]:
In [15]:
maxF = abs(sl1_lap[1,1]);
tol = 0.01;

#Ponovo, u zavisnosti od praga T vršimo odlučivanje da li neki piksel pripada ivici ili ne pripada 
#Za male T detekcija ivica će biti dobro izvršena
#Premala vrednost T će rezultovati detekcijom detalja koji nisu ivice, a preveliko T će imati
#kao posledicu previše propuštenih detekcija

(m, n) = size(sl1_lap);
for i in 1 : m, j in 1 : n
    if abs(sl1_lap[i,j]) > maxF
        maxF = abs(sl1_lap[i,j]);
    end
end


pripada_ivica1 = zeros(m,n);
T1 = 0.05 * maxF; 
for i in 1 : m, j in 1 : n
    if abs(sl1_lap[i,j]) > T1 
        pripada_ivica1[i,j] = 1;
    end
end

pripada_ivica2 = zeros(m,n);
T2 = 0.15 * maxF; 
for i in 1 : m, j in 1 : n
    if abs(sl1_lap[i,j]) > T2  
        pripada_ivica2[i,j] = 1;
    end
end

pripada_ivica3 = zeros(m,n);
T3 = 0.5 * maxF; 
for i in 1 : m, j in 1 : n
    if abs(sl1_lap[i,j]) > T3 
        pripada_ivica3[i,j] = 1;
    end
end




mosaicview(img,pripada_ivica1, pripada_ivica2, pripada_ivica3; nrow = 1 )
Out[15]:
In [ ]: